/******************************************************************************
**
** Copyright 2010-2012 Alexey Khomich
**
** File name:	reos.h
**
** Description:	ReOS (Real Time Operating System) Version 1.0 
**				For Atmel Xmega MCU targets.
**				
**				Application header file. Do not modify!!!
**
** Author:		Alexey.Khomich@gmail.com
**
*******************************************************************************
** History:		
**  
**	10/05/2011	- AK -	RTOS v2. TASK/ISR services reimplemented
**						kernel/task/isr typedefs are changed
**  10/15/2011	- AK - 	Adding basic event management
**	11/14/2011	- AK - 	Cosmetic changes (var names, defs)
** 	11/15/2011 	- AK - 	Adding messages, message queues and timers
**	11/19/2011 	- AK -	Removing obsolete services, about to final revision for 
**						RTOS V.2
**	11/25/2011  - AK -  Adding resourse export macros
**	09/05/2012  - AK -  RTOS_StackCheck() fix
**	09/20/2012	- AK -  RTOS_DECLARE_ISR() macro reimplemented
**						RTOS_STACKCHECK() services reimplemeted
**	09/25/2012	- AK - 	RTOS_TaskResumeISR() / ReOS_TaskSuspendISR added
**	09/28/2012  - AK -  Safe call for RTOS_StackCheck() when stack checking
**						is switched off (#undefine RTOS_USE_STACKCHECK) 
**	10/09/2012  - AK -  Added timer message RTOS feature (services & 
**						configuration)
**	10/09/2012  - AK -  Add RTOS_DECLARE_FAST_ISR()
**
**  01/29/2014  - AK -  Now moving to ReOS!!! 
** 
******************************************************************************/
#ifndef __ReOS_H__
#define __ReOS_H__

/******************************************************************************
** ReOS CONFIGURATION SECTION
******************************************************************************/
#define ReOS_VERSION_MAJOR				1		/* ReOS Version 1.0.0 */
#define ReOS_VERSION_MINOR				0
#define ReOS_VERSION_BUILD				0

#define ReOS_USE_STACKCHECK				1		/* Enable/Disable run-time stack verification capabilities */

/******************************************************************************
**
** Compiler related defines 
**
******************************************************************************/
#if !defined( __GNUC__ )  /* Supporting GNU toolchain from AVR Studio 5.0 */
#error "Error: No compiler is supported other than GNU Toolchain"
#endif

#define FLASH			__attribute__ ((progmem))
#define EEPROM			__attribute__ ((section(".eeprom")))
#define NAKED			__attribute__ ((naked))
#define CTASK			__attribute__ ((OS_task)) 				/* formerly __attribute__((noreturn)) */
#define CMAIN			__attribute__ ((OS_main))				/* new in ReOS Version 3 */
#define NAKEDFUNC(A) 	void A( void )   NAKED;			\
						void A( void )
#define CTASKFUNC(A) 	void A( void ) 	 CTASK;			\
						void A( void )
#define CMAINFUNC()		int	main( void ) CMAIN;			\
						int main( void )
#define ReOS_API		 __attribute__ ((visibility ("default")))
#define OBSOLETE		 __attribute__ ((visibility ("hidden") ))


/******************************************************************************
** ReOS Type Definitions
******************************************************************************/
/* ReOS ELEMENTARY TYPES */
typedef unsigned char 	ReOS_U8_t;
typedef unsigned int  	ReOS_U16_t;
typedef unsigned long 	ReOS_U32_t;

/* ReOS KERNEL PRIVATE STRUCTURE */
typedef struct ReOS_KDATA_s
{
	struct ReOS_TCB_s *	queue;				// Head of the running tasks queue 
	struct ReOS_TCB_s *	running;			// Actually running task
	void *				stack;				// Kernel stack pointer
	ReOS_U8_t			level;				// System execution level 
	
}
ReOS_KDATA_t;

/* ReOS TASK CONTEXT */
/* ReOS CONTEXT TYPE */
typedef struct ReOS_CTX_s
{
	ReOS_U8_t				STACKTOP;		// Top of the task stack
	ReOS_U8_t				STATUSREG;		// MCU STATUS REGISTER
	ReOS_U8_t				R[32];			// REGISTERS R0 ... R31
	ReOS_U16_t				RETADDR;		// RETURN ADDRESS
//	U8			RET_HI;
//	U8			RET_LO;
}
ReOS_CTX_t, * ReOS_CTX_ptr;


/* ReOS TASK/ISR FUNCTIONS */
typedef void ( ReOS_TSK_t ) (void);
typedef void ( ReOS_ISR_t )	(void);

/* ReOS TCB - TASK CONFIGURATION BLOCK */
typedef struct ReOS_TCB_s					// ReOS Task Configuration Block (TCB)
{
    ReOS_U8_t *				stack;          // Start of stack (top address-1)
    ReOS_TSK_t *			task;   		// Entry point of code
    struct ReOS_PID_s *		pid;         	// Pointer to Task ID block
    ReOS_U8_t 				prio;       	// Priority of task (0-255)	
}
FLASH const ReOS_TCB_t;

/* ReOS PID - PROCESS (TASK) IDENTIFIER */
typedef struct ReOS_PID_s					
{
	struct ReOS_PID_s *		next;
	ReOS_U8_t	 			flag;
	ReOS_U8_t 				prio;
	ReOS_CTX_t *			sptr;
}
ReOS_PID_t, * ReOS_PID_ptr;

/* ReOS EVT - EVENT */
typedef struct ReOS_EVT_s
{
	struct ReOS_EVT_s *	next;
}
ReOS_EVT_t, * ReOS_EVT_ptr;

/* ReOS EST - EVENT STATE */
typedef enum ReOS_EST_e
{
	EVT_PEND	= 0,						// Event Pending 
	EVT_DONE	= 1,						// Event Done
	EVT_WAIT	= 2,						// Something is waiting for the event	
}
ReOS_EST_t, * ReOS_EST_ptr;

/* ReOS MSG - MESSAGE */
typedef struct ReOS_MSG_s
{
    struct ReOS_MSG_s *		next;
    struct ReOS_EVT_s		event;
}
ReOS_MSG_t, * ReOS_MSG_ptr;

/* ReOS MSQ - MESSAGE QUEUE */
typedef struct ReOS_MSQ_s
{
    struct ReOS_MSG_s *		top;			// List of messages
    struct ReOS_PID_s *		pid;			// List of processes 
}
ReOS_MSQ_t, * ReOS_MSQ_ptr;

/* ReOS TMR - TIMER */
typedef struct ReOS_TMR_s
{
    struct ReOS_TMR_s *		next;
    struct ReOS_EVT_s		event;
    ReOS_U16_t 				count;
}
ReOS_TMR_t, * ReOS_TMR_ptr;

/* ReOS TMS - TIMER MESSAGE */
typedef struct ReOS_TMS_s
{
	union
	{
		ReOS_MSG_t		msg;
		ReOS_TMR_t		tmr;
	};
	ReOS_MSQ_t	* msq;
}
ReOS_TMS_t, * ReOS_TMS_ptr;

/* ReOS OBJ - OBJECT */
typedef union ReOS_OBJ_u
{
	struct ReOS_PID_s		pid;
	struct ReOS_MSG_s		msg;
	struct ReOS_MSQ_s		msq;
	struct ReOS_TMR_s		tmr;
}
ReOS_OBJ_t, * ReOS_OBJ_ptr;

/******************************************************************************
** ReOS CONSTANT DEFINITIONS
******************************************************************************/
#if !defined(NULL)
#	define	NULL	0
#endif

#define NOTASK		((ReOS_TCB_t *)NULL)
#define NOMESSAGE	((ReOS_MSG_t *)NULL)
#define NOTIMER		((ReOS_TMR_t *)NULL)

/******************************************************************************
** TASK DECLARATION/DEFINITION MACRO
******************************************************************************/
#if defined(ReOS_USE_STACKCHECK)

#define ReOS_DECLARE_TASK( __task__ , __stack__ , __prio__ ) 		\
	ReOS_U8_t	__task__##STK[__stack__ + sizeof(ReOS_CTX_t) + 8];	\
	void		__task__##FNC ( void ) __attribute__ ((noreturn));	\
	ReOS_PID_t	__task__##PID;										\
	ReOS_TCB_t	__task__##TCB = 									\
	{																\
		&__task__##STK[sizeof(__task__##STK) - 5],					\
		&__task__##FNC,												\
		&__task__##PID,												\
		__prio__,													\
	};																\
	void __attribute__((optimize("Os"))) 							\
		ReOS_StackCheck##__task__( void ) {							\
			if ( ( *(long *)(&__task__##STK[0]) != 0xDEADBEAFUL) || \
			   ( *(long *)(&__task__##STK[sizeof(__task__##STK) - 4]  ) != 0xDEADBEAFUL ) )   \
			ReOS_HaltOS();		 									\
			return;													\
		}															\
	void __attribute__((optimize("Os"))) 							\
		ReOS_StackInit##__task__( void ) {							\
			*((unsigned long *)(&__task__##STK[ 0])) = 0xDEADBEAFUL;\
			*((unsigned long *)(&__task__##STK[sizeof(__task__##STK) - 4])) = 0xDEADBEAFUL;	\
			return;													\
		}
#else

#define ReOS_DECLARE_TASK( __task__ , __stack__ , __prio__ ) 		\
	ReOS_U8_t	__task__##STK[__stack__ + sizeof(ReOS_CTX_t)];		\
	void		__task__##FNC ( void ) __attribute__ ((noreturn));	\
	ReOS_PID_t	__task__##PID;										\
	ReOS_TCB_t	__task__##TCB = 									\
	{																\
		&__task__##STK[sizeof(__task__##STK) - 1],					\
		&__task__##FNC,												\
		&__task__##PID,												\
		__prio__,													\
	}

#endif /* if defined(ReOS_USE_STACKCHECK) */
	
#define ReOS_TASK_FUNC( __task__ )									\
	CTASKFUNC(__task__##FNC)
		
/******************************************************************************
** ReOS INTERRUPT SERVICE ROUTINE DECLARATION/DEFINITION MACRO 
******************************************************************************/
#define STRINGIFY(x)	#x

#define ReOS_DECLARE_ISR( __vector__ , __handler__ )				\
	extern void __handler__ ## FNC ( void );						\
	NAKEDFUNC( __vector__ ) {										\
		asm volatile ( 												\
			"CLI\n"													\
			"CALL 	ReOS_EnterISR\n"								\
			"SEI\n"													\
			STRINGIFY( CALL 	__handler__ ## FNC\n )				\
			"JMP 	ReOS_LeaveISR\n"								\
			: : 													\
		);															\
	}


#define ReOS_DECLARE_FAST_ISR( __vector__ , __handler__ )			\
	extern void __handler__ ## ASM ( void );						\
	void __attribute__((signal, naked, used, externally_visible)) 	\
		__vector__ (void) { 										\
			asm volatile (											\
				STRINGIFY( JMP __handler__ ## ASM \n) 				\
				: :													\
			); 														\
		}
   
#define ReOS_ISR_FUNC( __handler__ )								\
	void __handler__ ## FNC ( void ) 

/******************************************************************************
** ReOS RESOURCES (EVENT/MESSAGE/QUEUE/TIMER) DECLARATION/DEFINITION MACRO 
******************************************************************************/
#define ReOS_DECLARE_EVENT( __evt__ )								\
	ReOS_EVT_t		__evt__

#define ReOS_DECLARE_MESSAGE( __msg__ )								\
    ReOS_MSG_t 		__msg__
	
#define ReOS_DECLARE_MESSAGE_EXP( __msg__ )							\
    ReOS_MSG_t 		__msg__;										\
	void *			__msg__##_dptr

#define ReOS_DECLARE_MESSAGEQ( __msq__ )							\
    ReOS_MSQ_t		__msq__

#define ReOS_DECLARE_TIMER( __tmr__ )								\
	ReOS_TMR_t		__tmr__
	
#define ReOS_DECLARE_TIMER_MESSAGE( __tms__ )						\
	ReOS_TMS_t		__tms__
	
/******************************************************************************
** ReOS RESOURCE (TASK/ISR/EVENT/MESSAGE/QUEUE/TIMER) EXPORT MACROS
******************************************************************************/	
#if defined(ReOS_USE_STACKCHECK)

#define EXPORT_ReOS_TASK( __tsk__ )									\
	extern void ReOS_StackCheck##__tsk__( void );					\
	extern void ReOS_StackInit##__tsk__( void );					\
	extern void __tsk__##FNC( void ) __attribute__((noreturn));		\
	extern ReOS_U8_t *	__tsk__##STK;								\
	extern ReOS_TCB_t 	__tsk__##TCB;	 							\
	extern ReOS_PID_t 	__tsk__##PID

#else

#define EXPORT_ReOS_TASK( __tsk__ )									\
	extern void __tsk__##FNC( void) __attribute__((noreturn));		\
	extern ReOS_TCB_t 	__tsk__##TCB;	 							\
	extern ReOS_PID_t 	__tsk__##PID
	
#endif


#define EXPORT_ReOS_ISR( __isr__ )									\
	extern void __isr__##FNC( void )
	
#define EXPORT_ReOS_EVENT( __evt__ )								\
	extern ReOS_EVT_t	__evt__

#define EXPORT_ReOS_MESSAGE( __msg__ ) 								\
	extern ReOS_MSG_t	__msg__

#define EXPORT_ReOS_MESSAGE_EXP(__msg__)							\
	extern ReOS_MSG_t	__msg__;									\
	extern void *		__msg__##_dptr
	
#define EXPORT_ReOS_MESSAGEQ( __msq__ ) 							\
	extern ReOS_MSQ_t	__msq__

#define EXPORT_ReOS_TIMER( __tmr__ ) 								\
	extern ReOS_TMR_t	__tmr__

#define EXPORT_ReOS_TIMER_MESSAGE( __tms__ ) 						\
	extern ReOS_TMS_t	__tms__
	
/******************************************************************************
** ReOS API SERVICES
******************************************************************************/

/* ReOS KERNEL MANAGEMENT API */

#			define		ReOS_DisableInterrupt() asm volatile ("cli\n")
#			define		ReOS_EnableInterrupt()  asm volatile ("sei\n")
#			define 		ReOS_HaltOS()			asm volatile ("break\n")

ReOS_API 	void * 		ReOS_Initialize			( void * sptr );
ReOS_API 	void 		ReOS_StartOS			( void );
ReOS_API 	void 		ReOS_EnterISR	   		( void );
ReOS_API 	void 		ReOS_LeaveISR			( void );
//OBSOLETE 	void 		ReOS_HaltOS				( void );		// Halt Processor (debug only)

/* ReOS TASK MANAGEMENT API */

#if defined(ReOS_USE_STACKCHECK)

#	define 	ReOS_TaskStartExp( __task__ )							\
				ReOS_StackInit##__task__();							\
				ReOS_TaskStart(&(__task__##TCB))
		
#	define 	ReOS_TaskInitExp( __task__ )							\
		ReOS_StackInit##__task__();									\
				ReOS_TaskInit(&(__task__##TCB))
		
#	define	ReOS_StackCheck( __task__ )								\
				ReOS_StackCheck##__task__()

#else

#	define 	ReOS_TaskStartExp( __task__ )							\
				ReOS_TaskStart(&(__task__##TCB))

#	define 	ReOS_TaskInitExp( __task__ )							\
				ReOS_TaskInit(&(__task__##TCB))
		
#	define	ReOS_StackCheck( __task__ )

		
#endif	/* if defined(ReOS_USE_STACKCHECK) */

ReOS_API 	void 		ReOS_TaskStart			( ReOS_TCB_t * );
ReOS_API unsigned char 	ReOS_TaskInit			( ReOS_TCB_t * );
ReOS_API 	void 		ReOS_TaskResume			( ReOS_PID_t * );
ReOS_API 	void 		ReOS_TaskSuspend		( ReOS_PID_t * );
ReOS_API 	void 		ReOS_TaskTerminate		( ReOS_PID_t * );
ReOS_API 	void 		ReOS_TaskExit			( void );
// obsolete ReOS_API ReOS_U8_t		ReOS_TaskGetPriority( ReOS_PID_t * );
// obsolete ReOS_API ReOS_U8_t		ReOS_TaskSetPriority( ReOS_PID_t * , ReOS_U8_t );
// obsolete ReOS_API ReOS_PID_t *	ReOS_TaskGetId( void );
ReOS_API 	void 		ReOS_WaitTask			( ReOS_PID_t * );
ReOS_API 	void 		ReOS_TaskYield			( void );
ReOS_API 	void 		ReOS_TaskYieldISR		( void );
#			define 		ReOS_GetTCB(__task__) 	&(__task__##TCB)
#			define 		ReOS_GetPID(__task__) 	&(__task__##PID)
ReOS_API	void 		ReOS_TaskResumeISR		( ReOS_PID_t * );
ReOS_API	void 		ReOS_TaskSuspendISR		( ReOS_PID_t * );


/* ReOS EVENT MANAGEMENT API  */

ReOS_API 	void 		ReOS_SetEvent			( ReOS_EVT_t * );
ReOS_API 	void 		ReOS_SetEventISR		( ReOS_EVT_t * );		// formerly ReOS_IntSetEvent
ReOS_API 	void 		ReOS_WaitEvent			( ReOS_EVT_t * );

ReOS_API ReOS_EST_t		ReOS_TestEvent			( ReOS_EVT_t * );
ReOS_API ReOS_EST_t 	ReOS_TestEventISR		( ReOS_EVT_t * );		// formerly ReOS_TestEventISR

ReOS_API 	void 		ReOS_ResetEvent			( ReOS_EVT_t * );
ReOS_API 	void 		ReOS_ResetObjectEvent	( ReOS_OBJ_t * );		// obsolete, to be used only inside Kernel 

ReOS_API ReOS_EST_t 	ReOS_TestTaskID			( ReOS_PID_t * );		// is it really needed

/* ReOS MESSAGE MANAGEMENT API */

#define ReOS_GetMessageData(__msg__,__type__) 				\
	(*((__type__*)(__msg__##_dptr)))
	
#define ReOS_PutMessageData(__msg__,__data__,__type__)		\
	*((__type__*)(__msg__##_dptr)) = *(&__data__)

ReOS_API ReOS_MSG_t *	ReOS_RecvMessage		( ReOS_MSQ_t * );
ReOS_API ReOS_MSG_t * 	ReOS_WaitMessage		( ReOS_MSQ_t * );
ReOS_API 	void 		ReOS_SendMessage		( ReOS_MSQ_t * , ReOS_MSG_t * );
ReOS_API 	void 		ReOS_SendMessageISR		( ReOS_MSQ_t * , ReOS_MSG_t * );
ReOS_API 	void 		ReOS_AckMessage			( ReOS_MSG_t * );
ReOS_API 	void 		ReOS_WaitMessageAck		( ReOS_MSG_t * );
ReOS_API ReOS_EST_t 	ReOS_TestMessageAck		( ReOS_MSG_t * );

/* ReOS TIMER MANAGEMENT API */

ReOS_API 	void 		ReOS_StartTimer			( ReOS_TMR_t * , ReOS_U16_t count );
ReOS_API ReOS_TMR_t * 	ReOS_CancelTimer		( ReOS_TMR_t * );
ReOS_API 	void 		ReOS_Delay				( ReOS_TMR_t * , ReOS_U16_t count);
ReOS_API 	void 		ReOS_WaitTimer			( ReOS_TMR_t * );
ReOS_API ReOS_EST_t  	ReOS_TestTimer			( ReOS_TMR_t * );

ReOS_API	void		ReOS_StartTimerMessage	( ReOS_TMS_t * , ReOS_U16_t , ReOS_MSQ_t * );
ReOS_API ReOS_MSG_t *	ReOS_CancelTimerMessage	( ReOS_TMS_t * , ReOS_MSQ_t * );

ReOS_API ReOS_U16_t		ReOS_GetTime			( void );
ReOS_API ReOS_U16_t		ReOS_GetTimeISR			( void );

ReOS_API 	void 		ReOS_TimerHandlerFNC	( void );    // Kernel Function called by timer ISR

/* ReOS TIMER MESSAGE MANAGEMENT API */

// -= TBD =- ReOS_API 	void 		ReOS_StartTimerMessage	( ReOS_TMS_t * timer , ReOS_U16_t count , ReOS_MSQ_t * queue);
// -= TBD =- ReOS_API pReOSMessage 	ReOS_CancelTimerMessage	( ReOS_TMS_t * timer , ReOS_MSQ_t * queue );

/******************************************************************************
** ReOS Debug Log services                                                                   
******************************************************************************/

OBSOLETE	void		ReOS_DebugOutPtr		( void * );				
OBSOLETE	void		ReOS_DebugOutByte		( ReOS_U8_t );			
OBSOLETE	void		ReOS_DebugOutBuff		( void * , ReOS_U8_t );	

ReOS_API	void		ReOS_DebugOutSync		( void );
ReOS_API	void		ReOS_DebugOutAddr		( void * );				
ReOS_API	void		ReOS_DebugOutData		( void * , ReOS_U8_t );				
ReOS_API	void		ReOS_DebugOutDump		( void );

/* ReOS_debug_ex.S */
ReOS_API	void 		ReOS_DebugOutArgs		( const char * fmt, ... );
ReOS_API	void 		ReOS_DebugOutKDump		( void );

/******************************************************************************
** EOF                                                                  
******************************************************************************/
#endif /* __ReOS_H__ */
